home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Camelot
/
Camelot 098 (1990-12)(Swedish User Group of Amiga)(SE)(PD)[WB].zip
/
Camelot 098 (1990-12)(Swedish User Group of Amiga)(SE)(PD)[WB].adf
/
XLisp-Stat
/
Functions
/
symbolicdiff.lsp
< prev
next >
Wrap
Lisp/Scheme
|
1990-10-11
|
3KB
|
85 lines
; book pp.110-117
(defun deriv (exp var)
(cond
((constantp exp) 0)
((variablep exp) (if (same-variable-p exp var) 1 0))
((sump exp)
(make-sum (deriv (addend exp) var)
(deriv (augend exp)var)))
((productp exp)
(make-sum (make-product (multiplier exp)
(deriv (multiplicand exp) var))
(make-product (deriv (multiplier exp) var)
(multiplicand exp))))
((unary-p exp)
(make-product (make-unary-deriv (unary-function exp)
(unary-argument exp))
(deriv (unary-argument exp) var)))
(t (error "Can't differentiate this expression"))))
(defun addend (e) (second e))
(defun augend (e) (third e))
(defun make-sum (a1 a2)
(cond
((and (numberp a1) (numberp a2)) (+ a1 a2))
((numberp a1) (if (= a1 0) a2 (list '+ a1 a2)))
((numberp a2) (if (= a2 0) a1 (list '+ a1 a2)))
(t (list '+ a1 a2))))
(defun multiplier (e) (second e))
(defun multiplicand (e) (third e))
(defun make-product (m1 m2)
(cond
((and (numberp m1) (numberp m2)) (* m1 m2))
((numberp m1)
(cond ((= m1 0) 0)
((= m1 1) m2)
(t (list '* m1 m2))))
((numberp m2)
(cond ((= m2 0) 0)
((= m2 1) m1)
(t (list '* m1 m2))))
(t (list '* m1 m2))))
(defun constantp (e) (numberp e))
(defun variablep (e) (symbolp e))
(defun same-variable-p (v1 v2)
(and (variablep v1) (variablep v2) (eq v1 v2)))
(defun sump (e)
(and (listp e) (= (length e) 3) (eq (first e) '+)))
(defun productp (e)
(and (listp e) (= (length e) 3) (eq (first e) '*)))
#|
(defun make-unary-deriv (fcn arg)
(case fcn
(exp (make-unary 'exp arg))
(sin (make-unary 'cos arg))
(cos (make-product -1 (make-uanry 'sin arg)))
(t (error "Can't differentiate this expression"))))
|#
(defun make-unary-deriv (fcn arg)
(apply-unary-rule (get-unary-rule fcn) arg))
(defun unary-p (e)
(and (listp e) (= (length e) 2)))
(defun unary-function (e) (first e))
(defun unary-argument (e) (second e))
(defun make-unary (fcn arg) (list fcn arg))
(def *derivatives* nil)
(defun add-unary-rule (f rule)
(setf *derivatives* (cons (list f rule) *derivatives*)))
(defun get-unary-rule (f)
(let ((rule (assoc f *derivatives*)))
(if rule
rule
(error "Can't differentiate this expression"))))
(defun apply-unary-rule (entry arg)
(funcall (second entry) arg))
(add-unary-rule 'exp #'(lambda (x) (make-unary 'exp x)))
(add-unary-rule 'sin #'(lambda (x) (make-unary 'cos x)))
(add-unary-rule 'cos
#'(lambda (x)
(make-product -1 (make-unary 'sin x))))